Skip to content

Conversation

@faisalsiddique4400
Copy link
Contributor

@faisalsiddique4400 faisalsiddique4400 commented Nov 25, 2025

fix(admin): description missing in client view details and alignment issues in fields (#2471)

Summary

The View Details mode in the Auth Server → Clients page does not display the description field. Several field values are also misaligned, resulting in inconsistent formatting throughout the details panel.

Issues Fixed

  • Description field not visible in the View Details dropdown.
  • Multiple alignment issues across value rows.
  • Inconsistent spacing and label–value layout in the details container.

Steps to Reproduce

  1. Go to Auth Server.
  2. Open Clients.
  3. Click the View Details dropdown on any client.
  4. Observe:
    • Description is not displayed.
    • Misalignment of several field values.

Expected Behavior

  • The description should appear correctly under the client details.
  • All fields should follow a consistent alignment.
  • Labels and values should match the UI pattern used across other View screens.

Fix Summary

  • Restored mapping for the description attribute.
  • Standardized alignment using Admin UI detail layout rules.
  • Adjusted spacing and corrected CSS classes for value alignment.

Closes

Closes: #2471

Summary by CodeRabbit

  • New Features

    • Configurable detail rows: adjustable label/value sizing, custom label styling, and optional per-row class names.
    • Two-column client detail layout with consistent, scrollable styling and reuseable secret display (toggleable visibility) and badge list rendering.
  • Refactor

    • Standardized detail layout, spacing and label alignment across pages.
    • Memoization and streamlined rendering to reduce unnecessary re-renders and improve performance.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 2025

📝 Walkthrough

Walkthrough

Refactors Gluu detail components to add typed public props, configurable sizes and label styles, memoization, and a computed row class; standardizes Clients detail layout with module-level style objects, badge-list helper, consistent FormGroup-based rows, and a toggleable secret display when appropriate.

Changes

Cohort / File(s) Summary
Gluu secret detail
admin-ui/app/routes/Apps/Gluu/GluuSecretDetail.tsx
Added GluuSecretDetailProps (label, value, optional doc_category/doc_entry, lsize, rsize, labelStyle, rowClassName) with defaults; replaced internal toggle logic with a memoized callback; merged label styles and computed row class; conditional Toggle when value !== '-'; exported component wrapped in memo.
Gluu form detail row
admin-ui/app/routes/Apps/Gluu/GluuFormDetailRow.tsx
Added GluuFormDetailRowProps, default labelStyle, appliedLabelStyle merging, safe theme access, rowClassName support, badge color selection (prop or theme-derived); exported component wrapped in memo.
Clients detail page (Auth Server)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js
Replaced Container/Row/Col layout with module-scope CSS-in-JS style objects; derived description/displayName fallbacks; added renderBadgeList helper; refactored detail rendering into two-column grid using GluuFormDetailRow and GluuSecretDetail; unified label/value styling and list badge rendering.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant App as App / Store
  participant ClientUI as ClientDetailPage
  participant Row as GluuFormDetailRow
  participant Secret as GluuSecretDetail
  Note over ClientUI,Secret: ClientDetailPage renders detail rows using shared styles and sizing props
  App->>ClientUI: supply client row data
  ClientUI->>Row: render label + value (appliedLabelStyle, lsize/rsize)
  ClientUI->>Secret: render secret row (label,value,lsize,rsize,labelStyle)
  Secret->>Secret: determine hasToggle = (value !== '-')
  alt secret present
    User->>Secret: click Toggle
    Secret->>Secret: toggle masked/unmasked (useCallback)
    Secret-->>ClientUI: displayed secret updated in DOM
  else secret absent
    Secret-->>ClientUI: render dash, no Toggle
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify typings and default values in GluuSecretDetailProps and GluuFormDetailRowProps.
  • Check callers of GluuSecretDetail / GluuFormDetailRow for compatibility with new optional props.
  • Review renderBadgeList and list rendering for empty/edge cases.
  • Confirm useCallback/memo avoid stale closures and that memoization doesn't hide required updates.

Suggested reviewers

  • syntrydy
  • duttarnab
  • moabu

Poem

"I twitch my nose and tidy rows,
labels bold where moonlight shows,
badges hop and secrets peek,
toggles wink when values speak.
A rabbit’s hop — a cleaner view." 🐰

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary changes: fixing the missing description field and alignment issues in the Clients view details page.
Linked Issues check ✅ Passed All code changes directly address issue #2471: description field is restored in ClientDetailPage.js, and alignment/spacing issues are fixed through CSS-in-JS grid layout and consistent component styling.
Out of Scope Changes check ✅ Passed Changes to GluuSecretDetail.tsx and GluuFormDetailRow.tsx are necessary infrastructure improvements to support the alignment and styling fixes required in ClientDetailPage.js, directly enabling the resolution of issue #2471.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch admin-ui-issue-2471-view

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mo-auto mo-auto added comp-admin-ui Component affected by issue or PR kind-bug Issue or PR is a bug in existing functionality labels Nov 25, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (2)

20-30: Normalize description value to a single string

extractDescription currently returns result[0].values, which is likely an array. That means description can be either a string (row.description) or an array (from customAttributes), and an empty array will still be truthy so the final || dash fallback will not kick in. This can lead to odd rendering (concatenated values or blank output).

Consider normalizing to a single trimmed string:

-  function extractDescription(customAttributes) {
-    const result = customAttributes.filter((item) => item.name === 'description')
-    if (result && result.length >= 1) {
-      return result[0].values
-    }
-    return ''
-  }
+  function extractDescription(customAttributes = []) {
+    const attr = customAttributes.find((item) => item.name === 'description')
+    const values = attr?.values
+    const firstValue = Array.isArray(values) ? values[0] : values
+    return typeof firstValue === 'string' ? firstValue.trim() : ''
+  }
 
   const dash = '-'
-  const description = row.description || extractDescription(row.customAttributes || []) || dash
+  const description =
+    (typeof row.description === 'string' && row.description.trim()) ||
+    extractDescription(row.customAttributes || []) ||
+    dash

This guarantees description is always a string (or -), which should make rendering and formatting more predictable.


98-115: Consider adding a dash fallback for applicationType

subjectType falls back to dash, but applicationType is passed directly. If row.applicationType is ever missing/empty, this row will render a blank value instead of the placeholder you use elsewhere.

You can make it consistent with a small tweak:

-            <GluuFormDetailRow
-              label="fields.application_type"
-              value={row.applicationType}
+            <GluuFormDetailRow
+              label="fields.application_type"
+              value={row.applicationType || dash}

This keeps the visual language uniform across all scalar fields.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 135632a and 3eaf051.

📒 Files selected for processing (2)
  • admin-ui/app/routes/Apps/Gluu/GluuSecretDetail.tsx (2 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (1)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
🔇 Additional comments (8)
admin-ui/app/routes/Apps/Gluu/GluuSecretDetail.tsx (1)

7-7: Secret detail props and responsive sizing look good

Extending the props with lsize/rsize and providing defaults keeps existing usage working while allowing better alignment control in detail views. No issues here.

admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (7)

31-45: Detail layout style objects look consistent with the rest of the view

The detailContainerStyle, detailRowStyle, detailLabelStyle, and detailValueStyle definitions give you a clear, centralized way to standardize spacing and typography across all rows in this panel. This directly addresses the alignment/spacing issues described in the PR.


59-79: Top row (client_id + client_secret) uses the new standardized layout correctly

The first row now uses detailRowStyle plus GluuFormDetailRow for client_id and the updated GluuSecretDetail for the secret, which should align both columns cleanly and match the rest of the detail panel styling.


80-97: Description is now surfaced with sensible fallbacks

Using displayName = row.clientName || row.displayName || dash and description = row.description || extractDescription(...) || dash in combination with GluuFormDetailRow ensures both fields are always present in View Details, fulfilling the issue’s core requirement about the missing description. The label–value layout here is consistent with other rows.


116-149: Trusted-client and status rows now match the shared detail-row pattern

The new FormGroup + Label + Col structure with detailLabelStyle and detailValueStyle, plus theme-aware badges for trusted client and status, brings these booleans in line with the rest of the detail view. Alignment and spacing should be much more consistent than before.


151-168: Scopes and grant types correctly leverage renderBadgeList

Using FormGroup row with label sm={4} and value sm={8}, together with renderBadgeList(clientScopes) and renderBadgeList(row.grantTypes), gives a clean, multi-value display that aligns with other badge-based rows. This should fix the earlier misalignment for these collections.


169-186: Response types and login URIs rows are visually consistent with scopes/grant types

response_types and login_uris now follow the same pattern (label sm={4}, value sm={8}, renderBadgeList for arrays), so these sections will respect the shared spacing and alignment rules and avoid the previous layout drift.


187-212: Logout redirect URIs and authentication method rows align with the new detail layout

The logout_redirect_uris row uses the same badge helper and grid as the other URI lists, and authentication_method now renders a themed badge when present or a dash otherwise, inside detailValueStyle. This keeps the bottom rows visually consistent with the rest of the detail panel while covering the “no value” case explicitly.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (1)

20-26: Handle array return value from extractDescription.

The values property (plural naming suggests an array) is returned directly. If result[0].values is an array like ['description text'] or [], passing it to GluuFormDetailRow may cause rendering issues since the component likely expects a string. An empty array [] is truthy, so the dash fallback on line 29 won't trigger even when there's no description.

Apply this diff to properly handle array values:

 function extractDescription(customAttributes) {
   const result = customAttributes.filter((item) => item.name === 'description')
   if (result && result.length >= 1) {
-    return result[0].values
+    const values = result[0].values
+    return Array.isArray(values) ? (values.length > 0 ? values.join(', ') : '') : values
   }
   return ''
 }
♻️ Duplicate comments (1)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (1)

46-56: LGTM! Past review feedback addressed.

The renderBadgeList helper now consistently wraps both the badge list and the dash placeholder in the same <div style={detailValueStyle}> container, ensuring uniform label–value alignment across all rows regardless of whether items are present.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3eaf051 and fb7f6b2.

📒 Files selected for processing (2)
  • admin-ui/app/routes/Apps/Gluu/GluuSecretDetail.tsx (2 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (1)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
🔇 Additional comments (4)
admin-ui/app/routes/Apps/Gluu/GluuSecretDetail.tsx (3)

7-7: LGTM! Flexible sizing parameters added.

The addition of optional lsize and rsize parameters with sensible defaults (6/6) allows callers to customize column widths while maintaining backward compatibility. This supports the PR objective of standardizing layout across different views.


16-19: LGTM! Alignment and styling improvements applied.

The changes correctly address the alignment issues mentioned in the PR objectives:

  • align-items-center ensures proper vertical alignment between label and value
  • mb-2 provides consistent spacing between rows
  • Bold labels create visual hierarchy
  • Dynamic lsize enables flexible layout

These changes standardize the detail row layout as intended.


20-31: LGTM! Refactoring successfully implements the previous review feedback.

The value column restructuring looks excellent:

  • Flex layout with proper alignment and spacing addresses the formatting issues
  • wordBreak: 'break-all' handles long secret values gracefully
  • Line 26 correctly implements the fix from the previous review comment—the condition (value === '-' || up) ensures the dash placeholder renders even when up is false, preventing blank rows for clients without secrets
  • Toggle appropriately hidden for dash placeholders
  • Dynamic rsize enables flexible responsive layout

The refactoring successfully standardizes the detail row layout as intended by the PR objectives.

admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (1)

58-212: Well-structured refactor that addresses the PR objectives.

The layout refactor successfully:

  • Restores the missing description field with proper fallback logic
  • Standardizes alignment using consistent style objects (detailRowStyle, detailLabelStyle, detailValueStyle)
  • Consolidates badge rendering into the reusable renderBadgeList helper
  • Applies uniform spacing and structure across all detail rows

The changes align well with the stated goal of fixing alignment issues and displaying the description field in the Clients View Details panel.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (1)

41-51: extractDescription returns an array instead of a string, causing incorrect UI rendering.

The customAttributes structure stores values as an array (confirmed by codebase patterns at admin-ui/plugins/user-management/helper/validations.ts:104-105). When result[0].values is an array like ['My Description'], it gets passed to GluuFormDetailRow which expects a string, resulting in value?.toString() rendering as a comma-joined string instead of a single value.

  function extractDescription(customAttributes) {
    const result = customAttributes.filter((item) => item.name === 'description')
    if (result && result.length >= 1) {
-      return result[0].values
+      const values = result[0].values
+      return Array.isArray(values) ? values[0] : values
    }
    return ''
  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb7f6b2 and 017df2b.

📒 Files selected for processing (3)
  • admin-ui/app/routes/Apps/Gluu/GluuFormDetailRow.tsx (3 hunks)
  • admin-ui/app/routes/Apps/Gluu/GluuSecretDetail.tsx (1 hunks)
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
admin-ui/app/routes/Apps/Gluu/GluuSecretDetail.tsx (3)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (1)
  • useTranslation (33-33)
admin-ui/plugins/services/Components/Configuration/PersistenceDetail.js (1)
  • labelStyle (37-39)
admin-ui/plugins/admin/components/Webhook/ShortcodePopover.js (1)
  • Label (91-118)
🔇 Additional comments (11)
admin-ui/app/routes/Apps/Gluu/GluuFormDetailRow.tsx (3)

1-19: LGTM! Well-structured typed interface with appropriate prop definitions.

The new GluuFormDetailRowProps interface provides good type safety. The optional props with sensible defaults and the inclusion of CSSProperties for labelStyle align well with the PR's goal of standardizing alignment.


37-40: Good defensive programming with optional chaining on theme context.

The theme?.state?.theme safely handles cases where the theme context might not be fully initialized, preventing potential runtime errors.


59-59: LGTM! Memoization is appropriate for this presentational component.

Since the component's output depends solely on its props and theme context, memo helps avoid unnecessary re-renders when parent components update.

admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (4)

53-63: LGTM! Badge list helper correctly handles empty state with consistent alignment.

The renderBadgeList function now wraps both populated and empty states in the same detailValueStyle container, ensuring consistent label-value alignment as suggested in previous reviews.


67-118: LGTM! Description field is now properly displayed with consistent styling.

The description field is correctly mapped at line 109-117 with appropriate fallback logic, directly addressing the PR objective. The consistent use of lsize={4}, rsize={8}, detailLabelStyle, and rowClassName="align-items-start" ensures uniform alignment across all fields.


146-178: LGTM! Boolean fields rendered consistently with badge styling.

The is_trusted_client and status fields use the same layout pattern with proper badge colors and detailValueStyle wrapper for alignment consistency.


181-241: LGTM! Badge list fields follow consistent layout pattern.

All multi-value fields (scopes, grant_types, response_types, login_uris, logout_redirect_uris, authentication_method) use the renderBadgeList helper with consistent sm={4}/sm={8} column sizing and uniform styling.

admin-ui/app/routes/Apps/Gluu/GluuSecretDetail.tsx (4)

7-16: LGTM! Well-defined props interface with appropriate optional fields.

The GluuSecretDetailProps interface provides good type safety and consistency with GluuFormDetailRowProps, supporting the unified styling approach across detail components.


33-35: LGTM! Proper use of useCallback for stable handler reference.

Using useCallback with an empty dependency array ensures the handleSecret function maintains referential stability, which works well with the memo wrapper to prevent unnecessary re-renders.


51-56: LGTM! Dash placeholder rendering issue has been correctly addressed.

The condition (value === '-' || up) ensures the dash placeholder is displayed when no secret exists, while maintaining the reveal toggle behavior for actual secrets. This addresses the concern from previous reviews.


63-63: LGTM! Memoization is appropriate for this component.

The component is a good candidate for memo as it's primarily presentational with stable props.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 017df2b and 1650c9e.

📒 Files selected for processing (1)
  • admin-ui/app/routes/Apps/Gluu/GluuFormDetailRow.tsx (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
admin-ui/app/routes/Apps/Gluu/GluuFormDetailRow.tsx (3)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (3)
  • useTranslation (33-33)
  • theme (34-34)
  • selectedTheme (35-35)
admin-ui/plugins/services/Components/Configuration/PersistenceDetail.js (1)
  • labelStyle (37-39)
admin-ui/plugins/admin/components/Webhook/ShortcodePopover.js (1)
  • Label (91-118)
🔇 Additional comments (1)
admin-ui/app/routes/Apps/Gluu/GluuFormDetailRow.tsx (1)

7-19: Typed props, layout knobs, and memoization look good

The props interface, default values (including lsize/rsize), rowClassName pass‑through, and memo export make this detail row more predictable and reusable without introducing behavioral regressions.

Also applies to: 23-35, 59-59

@sonarqubecloud
Copy link

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (1)

51-57: Excellent! I found critical evidence. In ClientListPage.js line 121, there's a similar pattern:

org = results[0].values[0]

This confirms that values is indeed an array, and the correct pattern is to access values[0] to get the actual value. The extractDescription function in ClientDetailPage.js returns result[0].values (the entire array) instead of result[0].values[0] (the first element), which would render as [object Array] in the UI.

The original review comment is verified as correct.


Fix required: extractDescription returns an array instead of a string value.

The function returns result[0].values, which is an array. Based on the pattern in ClientListPage.js (line 121: results[0].values[0]), the correct approach is to return the first element of the values array.

Apply this fix:

 function extractDescription(customAttributes) {
   const result = customAttributes.filter((item) => item.name === 'description')
   if (result && result.length >= 1) {
-    return result[0].values
+    return result[0].values[0] || ''
   }
   return ''
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2252cd5 and e6e215e.

📒 Files selected for processing (1)
  • admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (1)
admin-ui/app/customColors.ts (1)
  • customColors (4-25)
🔇 Additional comments (3)
admin-ui/plugins/auth-server/components/Clients/ClientDetailPage.js (3)

11-40: LGTM: Static styles properly moved to module scope.

The style objects are now correctly defined at module scope, addressing the previous review comment. This prevents unnecessary object recreation on each render.


63-73: LGTM: Badge list helper with consistent container wrapping.

The renderBadgeList helper correctly addresses the previous review comment by always wrapping the output (badges or dash) in the same styled container, ensuring consistent alignment across all rows.


80-143: LGTM: Column 1 fields with consistent layout and styling.

All fields in the first column follow a consistent pattern with proper label sizing (lsize=4/rsize=8 or sm=4/sm=8), uniform label styling, and appropriate use of the renderBadgeList helper for array fields.

@moabu moabu merged commit 32270a4 into main Nov 26, 2025
9 checks passed
@moabu moabu deleted the admin-ui-issue-2471-view branch November 26, 2025 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp-admin-ui Component affected by issue or PR kind-bug Issue or PR is a bug in existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(admin): description in view detail mode not showing up and there are plenty of alignment issues with field's value in Clients

4 participants